/*
 * Copyright 2012 Finbudget.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package finbudgettable.client.ui.grid.cell;

import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class CellExtendableWrapper<C> implements Cell<C> {

    private final Cell<C> cell;
    private final Set<String> consumedEvents = new HashSet<String>();

    private List<BrowserEventListener<C>> browserEventListenerList;


    public CellExtendableWrapper(Cell<C> cell) {
        this.cell = cell;
        consumedEvents.addAll(cell.getConsumedEvents());
    }

    protected void addEvents(Set<String> events) {
        for (String event : events) {
            consumedEvents.add(event);
        }
    }

    @Override
    public boolean dependsOnSelection() {
        return cell.dependsOnSelection();
    }

    @Override
    public Set<String> getConsumedEvents() {
        return consumedEvents;
    }

    @Override
    public boolean handlesSelection() {
        return cell.handlesSelection();
    }

    @Override
    public boolean isEditing(Context context, Element parent, C value) {
        return cell.isEditing(context, parent, value);
    }

    @Override
    public void onBrowserEvent(Context context, Element parent, C value, NativeEvent event, ValueUpdater<C> valueUpdater) {
        if (browserEventListenerList != null) {
            for (BrowserEventListener<C> listener : browserEventListenerList) {
                if (listener.onBrowserEvent(context, parent, value, event, valueUpdater))
                    return;
            }
        }
        cell.onBrowserEvent(context, parent, value, event, valueUpdater);
    }

    public void addBrowserEventListener(BrowserEventListener<C> listener) {
        ensureBrowserEventListenerList().add(listener);
        addEvents(listener.getConsumedEvents());
    }

    @Override
    public void render(Context context, C value, SafeHtmlBuilder sb) {
        cell.render(context, value, sb);
    }

    @Override
    public boolean resetFocus(Context context, Element parent, C value) {
        return cell.resetFocus(context, parent, value);
    }

    @Override
    public void setValue(Context context, Element parent, C value) {
        cell.setValue(context, parent, value);
    }

    protected List<BrowserEventListener<C>> ensureBrowserEventListenerList() {
        if (browserEventListenerList == null) {
            browserEventListenerList = new ArrayList<BrowserEventListener<C>>();
        }
        return browserEventListenerList;
    }
}
